<script lang="tsx">
import { defineComponent } from 'vue'
import type { UploadCustomRequestOptions, UploadFileInfo, UploadSettledFileInfo } from 'naive-ui'
import { useMessage } from 'naive-ui'
import type { ListType, OnRemove } from 'naive-ui/es/upload/src/interface'
import { type WorksImgListItem, uploadFile } from '~/api'

export default defineComponent({
  props: {
    accept: String,
    max: Number,
    fileList: Array as PropType<WorksImgListItem[]>,
    validateFile: Function as PropType<(file: File) => (Promise<boolean> | boolean)>,
    listType: {
      type: String as PropType<ListType>,
      default: 'image',
    },
  },
  emits: ['success', 'updateFiles', 'updating', 'finally'],
  setup(props, { emit }) {
    const fileListRef = ref<UploadFileInfo[]>([])

    const message = useMessage()
    const customRequest = async ({
      file,
      data,
      headers,
      withCredentials,
      action,
      onFinish,
      onError,
      onProgress,
    }: UploadCustomRequestOptions) => {
      // const formData = new FormData()
      // if (data) {
      //   Object.keys(data).forEach((key) => {
      //     formData.append(
      //       key,
      //       data[key as keyof UploadCustomRequestOptions['data']],
      //     )
      //   })
      // }
      // formData.append(file.name, file.file as File)

      if (props.validateFile) {
        const bool = await props.validateFile(file.file as File)
        if (!bool) {
          nextTick(() => {
            fileListRef.value = fileListRef.value.slice(0, -1)
          })
          onError()
          return Promise.reject(new Error('validate error'))
        }
      }

      emit('updating')

      uploadFile(file.file as File, e => onProgress({ percent: e * 100 }))
        // .post(action as string, {
        //   withCredentials,
        //   headers: headers as Record<string, string>,
        //   body: formData,
        //   onUploadProgress: ({ percent }) => {
        //     onProgress({ percent: Math.ceil(percent) })
        //   },
        // })
        .then((res) => {
          message.success('上传成功')
          onFinish()

          const item = fileListRef.value?.find(d => d.id === file.id)

          if (item)
            item.id = res.data.id

          emit('updateFiles', fileListRef.value.map(d => d.id))
        })
        .catch(() => {
          onError()
        }).finally(() => {
          emit('finally')
        })
    }

    watch(() => props.fileList, initFileList, { immediate: true })

    function renderIcon(f: UploadSettledFileInfo) {
    }

    function initFileList() {
      if (!props.fileList?.length)
        return

      fileListRef.value = props.fileList.map(d => ({
        id: d.id,
        name: d.fileName,
        status: 'finished',
        url: d.fileUrl ? getAssetUrl(d.fileUrl) : null,
      }))
    }

    // function handleUpdateFileList(e) {
    //   console.log(e)
    // }

    const handleRemove: OnRemove = (opt) => {
      emit('updateFiles', opt.fileList.filter(d => d.id !== opt.file.id).map(d => d.id))
    }
    return {
      fileListRef,
      customRequest,
      renderIcon,
      handleRemove,
      // handleUpdateFileList,
    }
  },
})
</script>

<template>
  <n-upload
    v-model:file-list="fileListRef"
    multiple
    :custom-request="customRequest"
    :list-type="listType"
    :max="max"
    :accept="accept"
    @remove="handleRemove"
  >
    <!-- <n-button>上传文件</n-button> -->
    <div cursor="pointer" w="100px" h="100px" border="~ #ECECEC solid hover:primary " flex="~ justify-center items-center">
      <div class="i-carbon:add text-50px" />
    </div>
  </n-upload>
</template>
